package cn.zjutleo.village_server.service;

import cn.zjutleo.village_server.constants.HouseRentTypeConstants;
import cn.zjutleo.village_server.dto.HouseRentOrderDto;
import cn.zjutleo.village_server.entity.HouseRent;
import cn.zjutleo.village_server.entity.HouseRentOrder;
import cn.zjutleo.village_server.exception.apiException.daoException.SelectException;
import cn.zjutleo.village_server.mapper.HouseRentMapper;
import cn.zjutleo.village_server.mapper.HouseRentOrderMapper;
import cn.zjutleo.village_server.vo.HouseRentDetailVo;
import cn.zjutleo.village_server.vo.HouseRentRoughVo;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.util.List;

/**
 * @author : Qin Zhenghan
 * @date : Created in 2021/9/22
 * @description: 房屋出租业务类
 */
@Slf4j
@Service
public class HouseRentService {

    @Resource
    private HouseRentMapper houseRentMapper;

    @Resource
    private HouseRentOrderMapper houseRentOrderMapper;

    /**
     * 根据id查找房屋出租详细信息
     *
     * @param id 房屋出租id
     * @return 房屋出租详细信息
     * @throws SelectException 查询错误
     */
    public HouseRentDetailVo getHouseRentDetailVoById(Integer id) throws SelectException {
        HouseRentDetailVo houseRentDetailVo = houseRentMapper.selectDetailVoByPrimaryKey(id);
        if (houseRentDetailVo == null) {
            throw new SelectException("未找到该房屋出租信息！");
        }
        return houseRentDetailVo;
    }

    /**
     * 根据可选条件查询房屋出租粗略信息列表
     *
     * @param villageId 所属乡村id
     * @param type      出租类型
     * @param minPrice  价格下限
     * @param maxPrice  价格上限
     * @return 房屋粗略信息列表
     * @throws SelectException 查询错误
     */
    public List<HouseRentRoughVo> getHouseRentRoughVosByConditions(Integer villageId,
                                                                   String type,
                                                                   Integer minPrice,
                                                                   Integer maxPrice,
                                                                   Integer closest) throws SelectException {
        Integer typeId = null;
        if (type != null) {
            switch (type) {
                case HouseRentTypeConstants.ENTIRE_RENT: {
                    typeId = 1;
                    break;
                }
                case HouseRentTypeConstants.JOINT_RENT: {
                    typeId = 2;
                    break;
                }
                case HouseRentTypeConstants.LONG_RENT: {
                    typeId = 3;
                    break;
                }
                case HouseRentTypeConstants.SHORT_RENT: {
                    typeId = 4;
                    break;
                }
                default: {
                    throw new SelectException("'type'参数取值错误！");
                }
            }
        }
        return houseRentMapper.selectRoughVosByConditions(villageId, typeId, minPrice, maxPrice, closest);
    }

    /**
     * 根据可选条件查询房租租赁详细信息列表
     *
     * @param minPrice 价格下限
     * @param maxPrice 价格上限
     * @param query    模糊查询
     * @param check    审核状态
     * @return 房屋租赁详细信息列表
     */
    public List<HouseRentDetailVo> getHouseRentDetailVosByConditions(Integer minPrice,
                                                                     Integer maxPrice,
                                                                     String query,
                                                                     Integer check) {
        return houseRentMapper.selectDetailVosByConditions(minPrice, maxPrice, query, check);
    }

    /**
     * 获取所有房屋租赁详细信息列表
     *
     * @return 所有房屋租赁详细信息列表
     */
    public List<HouseRentDetailVo> getHouseRentDetailVos() {
        return houseRentMapper.selectDetailVos();
    }

    /**
     * 按照价格区间查询房屋租赁详细信息列表
     *
     * @param minPrice 价格下限
     * @param maxPrice 价格上限
     * @return 房屋租赁详细信息列表
     */
    public List<HouseRentDetailVo> selectHouseRentDetailVosByPrice(Integer minPrice, Integer maxPrice) {
        return houseRentMapper.selectDetailVosByPrice(minPrice, maxPrice);
    }

    /**
     * 根据描述模糊查询房屋租赁详细信息列表
     *
     * @param query 查询字符串
     * @return 房屋租赁详细信息列表
     */
    public List<HouseRentDetailVo> selectHouseRentDetailVosByFuzzyIntro(String query) {
        return houseRentMapper.selectDetailVosByIntro(query);
    }

    /**
     * 根据id与状态参数修改房屋租赁审核状态
     *
     * @param rentId 房屋租赁id
     * @param status 审核状态
     */
    public void changeHouseRentCheckStatus(Integer rentId, Integer status) {
        HouseRent houseRent = getHouseRentById(rentId);
        houseRent.setCheck(status);
        houseRentMapper.updateByPrimaryKeySelective(houseRent);
    }

    /**
     * 添加房屋预约信息并返回房屋租赁订单号
     *
     * @param houseRentOrderDto 房屋预约DTO
     * @param userId            用户id
     * @throws SelectException  查找不存在异常
     */
    @Transactional(rollbackFor = Exception.class)
    public Integer addHouseRentOrder(HouseRentOrderDto houseRentOrderDto, Integer userId) throws SelectException {
        if (houseRentOrderMapper.selectByTenantIdAndRentId(userId, houseRentOrderDto.getRentId()) != null) {
            updateHouseRentOrder(houseRentOrderDto, userId);
            return getHouseRentOrderIdByIds(houseRentOrderDto.getRentId(), userId, houseRentOrderDto.getHostId());
        } else {
            HouseRentOrder houseRentOrder = new HouseRentOrder();
            houseRentOrder.setTenantId(userId);
            houseRentOrder.setRentId(houseRentOrderDto.getRentId());
            houseRentOrder.setHostId(houseRentOrderDto.getHostId());
            houseRentOrder.setOrderTime(houseRentOrderDto.getOrderTime());
            houseRentOrderMapper.insertSelective(houseRentOrder);
            return getHouseRentOrderIdByIds(houseRentOrderDto.getRentId(), userId, houseRentOrderDto.getHostId());
        }
    }

    /**
     * 获取所有房屋租赁订单
     *
     * @return 房屋租赁订单列表
     */
    public List<HouseRentOrder> getAllHouseRentOrder() {
        return houseRentOrderMapper.selectAllHouseRentOrder();
    }

    /**
     * 根据房屋租赁订单号查询房屋租赁详细信息
     *
     * @param orderId 房屋租赁订单号
     * @return 房屋租赁详细信息
     */
    public HouseRentDetailVo getHouseRentDetailVoByOrderId(Integer orderId) {
        HouseRentOrder houseRentOrder = houseRentOrderMapper.selectByPrimaryKey(orderId);
        return houseRentMapper.selectDetailVoByPrimaryKey(houseRentOrder.getRentId());
    }

    /**
     * 更新房屋预约信息
     *
     * @param houseRentOrderDto 房屋预约DTO
     * @param userId            用户id
     * @throws SelectException  查找不存在异常
     */
    private Integer updateHouseRentOrder(HouseRentOrderDto houseRentOrderDto, Integer userId) throws SelectException {
        HouseRentOrder houseRentOrder = houseRentOrderMapper.selectByTenantIdAndRentId(userId, houseRentOrderDto.getRentId());
        if (houseRentOrder == null) {
            throw new SelectException("预约信息不存在！");
        }
        houseRentOrder.setOrderTime(houseRentOrderDto.getOrderTime());
        return houseRentOrderMapper.updateByPrimaryKeySelective(houseRentOrder);
    }

    /**
     * 根据id获取房屋租赁实体类
     *
     * @param rentId 房屋租赁id
     * @return 房屋租赁实体
     */
    private HouseRent getHouseRentById(Integer rentId) {
        return houseRentMapper.selectByPrimaryKey(rentId);
    }

    /**
     * 获取房屋租赁订单号
     *
     * @param rentId   房屋租赁id
     * @param tenantId 租客id
     * @param hostId   房东id
     * @return 房屋租赁订单号
     */
    private Integer getHouseRentOrderIdByIds(Integer rentId, Integer tenantId, Integer hostId) {
        return houseRentOrderMapper.selectPrimaryKeyByIds(rentId, tenantId, hostId);
    }
}
